#pragma once

#include "common.hpp"

class NamedPipe
{
public:
    NamedPipe(const std::string &pipe_name, mode_t mode)
        : _pipe_name(pipe_name), _mode(mode), _fd(-1) {}
    ~NamedPipe()
    {
        if (_fd != -1)
        {
            close(_fd);
            _fd = -1;
        }
    }
    bool Create()
    {
        int n = mkfifo(PIPE_NAME.c_str(), mode);
        if (n == 0)
            std::cout << "mkfifo success" << std::endl;
        else
        {
            perror("mkfifo");
            return false;
        }
        return true;
    }
    bool OpenForRead()
    {
        _fd = open(_pipe_name.c_str(), O_RDONLY);
        if (_fd == -1)
        {
            perror("open");
            return false;
        }
        std::cout << "open for read success" << std::endl;
        return true;
    }
    bool OpenForWrite()
    {
        _fd = open(_pipe_name.c_str(), O_WRONLY);
        if (_fd == -1)
        {
            perror("open");
            return false;
        }
        std::cout << "open for write success" << std::endl;
        return true;
    }
    bool Read(std::string *out)
    {
        char buf[SIZE];
        ssize_t s = read(_fd, buf, SIZE - 1);
        if (s > 0)
        {
            buf[s] = 0;
            *out = buf;
        }
        else if (s == 0)
        {
            return false;
        }
        else
        {
            perror("read");
            return false;
        }
        return true;
    }
    bool Write(const std::string &in)
    {
        return write(_fd, in.c_str(), in.size()) != -1;
    }

    void Close()
    {
        if (_fd == -1)
            return;
        close(_fd);
    }

    void Remove()
    {
        unlink(_pipe_name.c_str());
    }

private:
    // string path;
    std::string _pipe_name;
    mode_t _mode;
    int _fd;
};